CREATE OR REPLACE EDITIONABLE PACKAGE BODY "SCOTT"."PKG_MODEL_STOCK_ANALYSIS" is

  /*---------------------------- 计算model_stock_analysis表的全部数据 --------------------------------*/
  procedure write_mdl_stock_analysis as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当日股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_all_stock_transaction_data is
      select * from stock_transaction_data;
  begin
    for i in cur_all_stock_transaction_data loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_ma_trend(to_char(i.date_,
                                                           'yyyy-MM-dd'),
                                                   i.code_);
    
      -- 判断当日股价的涨跌
      v_up_down := i.up_down;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_analysis中插入数据
      insert into mdl_stock_analysis
        (date_,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.date_,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_stock_analysis;

  /*------------------------ 计算model_stock_analysis表再某一日的数据 ----------------------------*/
  procedure write_mdl_s_a_by_date(p_date in varchar2) as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当日股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_stock_transac_data_by_date is
      select *
        from stock_transaction_data t
       where t.date_ = to_date(p_date, 'yyyy-mm-dd');
  begin
    for i in cur_stock_transac_data_by_date loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_ma_trend(to_char(i.date_,
                                                           'yyyy-MM-dd'),
                                                   i.code_);
    
      -- 判断当日股价的涨跌
      v_up_down := i.up_down;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_analysis中插入数据
      insert into mdl_stock_analysis
        (date_,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.date_,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_s_a_by_date;

  /*---------------------------- 计算model_stock_week_analysis表的全部数据 --------------------------------*/
  procedure write_mdl_stock_week_analysis as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当周股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_all_stock_week is
      select * from stock_week;
  begin
    for i in cur_all_stock_week loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_week_ma_trend(to_char(i.begin_date,
                                                                'yyyy-MM-dd'),
                                                        to_char(i.end_date,
                                                                'yyyy-MM-dd'),
                                                        i.code_);
    
      -- 判断当周股价的涨跌
      if i.open_price < i.close_price then
        v_up_down := 1;
      elsif i.open_price > i.close_price then
        v_up_down := -1;
      else
        v_up_down := 0;
      end if;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_week_analysis中插入数据
      insert into mdl_stock_week_analysis
        (begin_date,
         end_date,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.begin_date,
         i.end_date,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_stock_week_analysis;

  /*------------------------ 计算model_stock_week_analysis表再某一日的数据 ----------------------------*/
  procedure write_mdl_s_w_a_by_date(p_begin_date in varchar2,
                                    p_end_date   in varchar2) as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当周股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_stock_week_by_date is
      select *
        from stock_week t
       where t.begin_date between to_date(p_begin_date, 'yyyy-mm-dd') and
             to_date(p_end_date, 'yyyy-mm-dd')
         and t.end_date between to_date(p_begin_date, 'yyyy-mm-dd') and
             to_date(p_end_date, 'yyyy-mm-dd');
  begin
    for i in cur_stock_week_by_date loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_week_ma_trend(to_char(i.begin_date,
                                                                'yyyy-MM-dd'),
                                                        to_char(i.end_date,
                                                                'yyyy-MM-dd'),
                                                        i.code_);
    
      -- 判断当周股价的涨跌
      if i.open_price < i.close_price then
        v_up_down := 1;
      elsif i.open_price > i.close_price then
        v_up_down := -1;
      else
        v_up_down := 0;
      end if;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_analysis中插入数据
      insert into mdl_stock_week_analysis
        (begin_date,
         end_date,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.begin_date,
         i.end_date,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_s_w_a_by_date;

  /*---------------------------- 计算model_stock_month_analysis表的全部数据 --------------------------------*/
  procedure write_mdl_stock_month_analysis as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当日股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_all_stock_month is
      select * from stock_month;
  begin
    for i in cur_all_stock_month loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_month_ma_trend(to_char(i.begin_date,
                                                                 'yyyy-MM-dd'),
                                                         to_char(i.end_date,
                                                                 'yyyy-MM-dd'),
                                                         i.code_);
    
      -- 判断当日股价的涨跌
      if i.open_price < i.close_price then
        v_up_down := 1;
      elsif i.open_price > i.close_price then
        v_up_down := -1;
      else
        v_up_down := 0;
      end if;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_month_analysis中插入数据
      insert into mdl_stock_month_analysis
        (begin_date,
         end_date,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.begin_date,
         i.end_date,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_stock_month_analysis;

  /*------------------------ 计算model_stock_month_analysis表再某一日的数据 ----------------------------*/
  procedure write_mdl_s_m_a_by_date(p_begin_date in varchar2,
                                    p_end_date   in varchar2) as
    -- 表示macd趋势
    v_macd_trend number;
    -- 表示kd趋势
    v_kd_trend number;
    -- 表示ma趋势
    v_ma_trend number;
    -- 表示当日股价是涨是跌。1表示上涨，-1表示下跌，0表示平
    v_up_down number;
    -- 将收盘价和均线从高到低排序。0表示close_price，1表示ma5，2表示ma10，3表示ma20，4表示ma60，5表示ma120，6表示ma250
    v_close_price_ma_order varchar2(10) := '';
    -- 定义类型，表示收盘价
    t_close_price SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA5
    t_ma5 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA10
    t_ma10 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA20
    t_ma20 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA60
    t_ma60 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA120
    t_ma120 SCOTT.t_close_price_ma_order;
    -- 定义类型，表示MA250
    t_ma250 SCOTT.t_close_price_ma_order;
    -- 存储t_close_price_ma_order类型的数组
    t_close_price_ma_order_array SCOTT.t_close_price_ma_order_array;
    -- 平均数
    v_average number;
    -- 标准差
    v_standard_deviation number;
    -- 用于获取所有的STOCK_TRANSACTION_DATA记录
    cursor cur_stock_month_by_date is
      select *
        from stock_month t
       where t.begin_date between to_date(p_begin_date, 'yyyy-mm-dd') and
             to_date(p_end_date, 'yyyy-mm-dd')
         and t.end_date between to_date(p_begin_date, 'yyyy-mm-dd') and
             to_date(p_end_date, 'yyyy-mm-dd');
  begin
    for i in cur_stock_month_by_date loop
      -- 判断macd趋势
      if i.dif > i.dea then
        v_macd_trend := 1;
      elsif i.dif < i.dea then
        v_macd_trend := -1;
      else
        v_macd_trend := 0;
      end if;
    
      -- 判断kd趋势
      if i.k > i.d then
        v_kd_trend := 1;
      elsif i.k < i.d then
        v_kd_trend := -1;
      else
        v_kd_trend := 0;
      end if;
    
      -- 判断ma趋势
      v_ma_trend := SCOTT.fnc_judge_stock_month_ma_trend(to_char(i.begin_date,
                                                                 'yyyy-MM-dd'),
                                                         to_char(i.end_date,
                                                                 'yyyy-MM-dd'),
                                                         i.code_);
    
      -- 判断当日股价的涨跌
      if i.open_price < i.close_price then
        v_up_down := 1;
      elsif i.open_price > i.close_price then
        v_up_down := -1;
      else
        v_up_down := 0;
      end if;
    
      -- 将close_price、ma5、ma10、ma20、ma60、ma120、ma250降序排列
      t_close_price_ma_order_array := SCOTT.t_close_price_ma_order_array();
      t_close_price                := SCOTT.t_close_price_ma_order(i.close_price,
                                                                   'close_price',
                                                                   0);
      t_close_price_ma_order_array.extend;
      t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_close_price;
      if i.ma5 is not null then
        t_ma5 := SCOTT.t_close_price_ma_order(i.ma5, 'ma5', 1);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma5;
      end if;
      if i.ma10 is not null then
        t_ma10 := SCOTT.t_close_price_ma_order(i.ma10, 'ma10', 2);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma10;
      end if;
      if i.ma20 is not null then
        t_ma20 := SCOTT.t_close_price_ma_order(i.ma20, 'ma20', 3);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma20;
      end if;
      if i.ma60 is not null then
        t_ma60 := SCOTT.t_close_price_ma_order(i.ma60, 'ma60', 4);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma60;
      end if;
      if i.ma120 is not null then
        t_ma120 := SCOTT.t_close_price_ma_order(i.ma120, 'ma120', 5);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma120;
      end if;
      if i.ma250 is not null then
        t_ma250 := SCOTT.t_close_price_ma_order(i.ma250, 'ma250', 6);
        t_close_price_ma_order_array.extend;
        t_close_price_ma_order_array(t_close_price_ma_order_array.count) := t_ma250;
      end if;
      t_close_price_ma_order_array := SCOTT.fnc_sort_t_c_p_ma_order_array(t_close_price_ma_order_array);
    
      -- 拼接v_close_price_ma_order
      for i in 1 .. t_close_price_ma_order_array.count loop
        v_close_price_ma_order := v_close_price_ma_order || t_close_price_ma_order_array(i)
                                 .get_label;
      end loop;
    
      -- 计算标准差
      v_average            := (i.close_price + i.ma5 + i.ma10 + i.ma20 +
                              i.ma60 + i.ma120 + i.ma250) / 7;
      v_standard_deviation := sqrt((power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2) +
                                   power(i.close_price - v_average, 2)) / 6);
    
      -- 向表mdl_stock_analysis中插入数据
      insert into mdl_stock_month_analysis
        (begin_date,
         end_date,
         code_,
         ma_trend,
         macd_trend,
         kd_trend,
         up_down,
         close_price_ma_order,
         standard_deviation)
      values
        (i.begin_date,
         i.end_date,
         i.code_,
         v_ma_trend,
         v_macd_trend,
         v_kd_trend,
         v_up_down,
         v_close_price_ma_order,
         v_standard_deviation);
    
      -- 重置为空字符串
      v_close_price_ma_order := '';
    end loop;
    commit;
  end write_mdl_s_m_a_by_date;

end PKG_MODEL_STOCK_ANALYSIS;